﻿using EShop.Net.Auth;
using EShop.Net.IServices.User;
using EShop.Net.Loging;
using EShop.Net.Model;
using EShop.Net.Model.Entity;
using EShop.Net.Model.FromBody;
using EShop.Net.Util.Date;
using EShop.Net.WeChar.Client;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NLog;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using System;
using System.Security.Claims;
using System.Threading.Tasks;

namespace EShop.Net.API.Controllers
{
    /// <summary>
    /// 测试控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class TestController : ControllerBase
    {
        private IWebHostEnvironment evn { get; }  // web环境
        private readonly IUserServices _userIServices;

        public TestController(IUserServices userIServices, IWebHostEnvironment env)
        {
            _userIServices = userIServices;
            evn = env;
        }

        /// <summary>
        /// 【NOTTOKEN】获取用户数据（测试用）
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResponseResultJson> SelectUserInfo(int id)
        {
            var data = await this._userIServices.QueryListByClauseAsync(u => u.id <= id);
            NLogUtil.WriteAll(LogLevel.Error, LogType.Other, "NLog测试", "测试测试");
            return ResponseResultJson.ResponseResult(200, "Success", data);
        }

        /// <summary>
        /// 【ADMIN】获取用户数据（测试用）
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        [Authorize(Roles = "admin")]  // 权限认证
        public async Task<ResponseResultJson> AdminSelectUserInfo(int id)
        {
            var data = await this._userIServices.QueryListByClauseAsync(u => u.id <= id);
            return ResponseResultJson.ResponseResult(200, "Success", data);
        }

        /// <summary>
        /// 【USER】获取用户数据（测试用）
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        [Authorize(Roles = "user")]  // 权限认证
        public async Task<ResponseResultJson> UserSelectUserInfo(int id)
        {
            var data = await this._userIServices.QueryListByClauseAsync(u => u.id <= id);
            return ResponseResultJson.ResponseResult(200, "Success", data);
        }

        #region 登录相关

        /// <summary>
        /// 【ADMIN】获取Token（测试用）
        /// </summary>
        /// <param name="fromUserLogin">商家登录实体</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResponseResultJson> AdminLogin([FromBody] FBAdminLogin fromUserLogin)
        {
            try
            {
                var data = await this._userIServices.AdminLogin(fromUserLogin.UserName, fromUserLogin.UserPwd);
                if (data != null)
                {
                    Claim[] claims = new Claim[]
                    {
                        new Claim(ClaimTypes.Name, fromUserLogin.UserName),
                        new Claim(ClaimTypes.NameIdentifier, fromUserLogin.UserPwd),
                        new Claim(ClaimTypes.Role, "admin")
                    };
                    var token = JwtToken<UserInfo>.GetJwtToken(claims, evn.ContentRootPath, 0);
                    //token.userID = data.id;
                    return ResponseResultJson.ResponseResult(200, "Token:OK", token);
                }
                else
                {
                    return ResponseResultJson.ResponseResult(403, "账号或密码错误", null);
                }
            }
            catch (Exception ex)
            {
                NLogUtil.WriteAll(LogLevel.Error, LogType.DataBase, "【ADMIN】获取Token（测试用）", "AdminLogin控制器层", ex);
                return ResponseResultJson.ResponseResult(500, "Token:ERROR", null);
            }
        }

        /// <summary>
        /// 【USER】获取Token（测试用）
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResponseResultJson> UserLogin([FromBody] FBWeixinLogin entity)
        {
            try
            {
                WechatApiClientFactory wechatApiClientFactory = new WechatApiClientFactory();
                var client = wechatApiClientFactory.CreateWxClient();
                var request = new SnsJsCode2SessionRequest()
                {
                    JsCode = entity.code,
                    AccessToken = ""
                };
                var response = await client.ExecuteSnsJsCode2SessionAsync(request, HttpContext.RequestAborted);
                TokenObj<UserInfo> token = null;
                if (response.ErrorCode == 0)
                {
                    var userInfo = await this._userIServices.SelectUserByOpenId(response.OpenId);
                    if (userInfo == null)
                    {
                        userInfo = new UserInfo()
                        {
                            openId = response.OpenId,
                            sessionKey = response.SessionKey,
                            unionId = response.UnionId,
                            nickName = entity.nickName,
                            avatarImage = entity.avatarUrl,
                            createTime = DateTimeHelper.BeijingTimeToUnixTimeStamp13(DateTime.Now),
                            gender = 3,
                            status = 0
                        };
                        await this._userIServices.InsertAsync(userInfo);
                    }
                    else
                    {
                        if (userInfo.sessionKey != response.SessionKey)
                        {
                            var res = await this._userIServices.UpdateByUserOpenid(response.OpenId, response.SessionKey, entity.nickName, entity.avatarUrl);
                        }
                    }
                    var user = await this._userIServices.QueryListByClauseAsync(u => u.openId.Equals(userInfo.openId));
                    Claim[] claims = new Claim[]
                    {
                        new Claim(ClaimTypes.Name, user[0].nickName),
                        new Claim(ClaimTypes.NameIdentifier, user[0].openId),
                        new Claim(ClaimTypes.Role, "user")
                    };
                    token = JwtToken<UserInfo>.GetJwtToken(claims, evn.ContentRootPath, 1);
                }
                return ResponseResultJson.ResponseResult(200, "Token:OK", token);
            }
            catch (Exception ex)
            {
                NLogUtil.WriteAll(LogLevel.Error, LogType.DataBase, "【USER】获取Token（测试用）", "UserLogin控制器层", ex);
                return ResponseResultJson.ResponseResult(500, "Token:ERROR", null);
            }
        }

        #endregion
    }
}
